#include <ximera/graphics/ogre/viewport.hpp>
#include <ximera/graphics/ogre/graphicssystem.hpp>
#include <ximera/graphics/ogre/camera.hpp>

namespace ximera { namespace graphics { namespace ogre
{
    Viewport::Viewport(GraphicsSystem* graphicsSystem, Camera* camera)
        : _graphicsSystem(graphicsSystem),
          _camera(0)
    {
        XIMERA_ASSERT(camera && graphicsSystem, XIMERA_THROW(OgreException, L"Missing camera or graphics system!"));

        _ogreViewport = graphicsSystem->ogreWindow()->addViewport(camera->ogreCamera());
        XIMERA_ASSERT(_ogreViewport, XIMERA_THROW(OgreException, L"Could not create viewport"));

        _ogreViewport->setBackgroundColour(Ogre::ColourValue(0,0,0,0));
    }

    Viewport::~Viewport()
    {
        // removeViewport destroys the object
        _graphicsSystem->ogreWindow()->removeViewport(_ogreViewport->getZOrder());
    }

    Real Viewport::left() const
    {
        return _ogreViewport->getLeft();
    }

    Real Viewport::actualLeft() const
    {
        return _ogreViewport->getActualLeft();
    }

    void Viewport::left(Real value)
    {
        _ogreViewport->setDimensions(value, top(), width(), height());
    }

    Real Viewport::top() const
    {
        return _ogreViewport->getTop();
    }

    Real Viewport::actualTop() const
    {
        return _ogreViewport->getActualTop();
    }

    void Viewport::top(Real value)
    {
        _ogreViewport->setDimensions(left(), value, width(), height());
    }

    Real Viewport::width() const
    {
        return _ogreViewport->getWidth();
    }

    Real Viewport::actualWidth() const
    {
        return _ogreViewport->getActualWidth();
    }

    void Viewport::width(Real value)
    {
        _ogreViewport->setDimensions(left(), top(), value, height());
    }

    Real Viewport::height() const
    {
        return _ogreViewport->getHeight();
    }
    
    Real Viewport::actualHeight() const
    {
        return _ogreViewport->getActualHeight();
    }

    void Viewport::height(Real value)
    {
        _ogreViewport->setDimensions(left(), top(), width(), value);
    }

    void Viewport::resize(Real left, Real top, Real width, Real height)
    {
        _ogreViewport->setDimensions(left, top, width, height);
    }

    ICamera* Viewport::camera()
    {
        return _camera;
    }

    void Viewport::camera(ICamera* cam)
    {
        _camera = static_cast<Camera*>(cam);

        if (_camera)
            _ogreViewport->setCamera(_camera->ogreCamera());
        else
            _ogreViewport->setCamera(0);
    }

    math::Color Viewport::backgroundColor() const
    {
        Ogre::ColourValue const& ogreColor = _ogreViewport->getBackgroundColour();
        return math::Color(ogreColor.r, ogreColor.g, ogreColor.b, ogreColor.a);
    }

    void Viewport::backgroundColor(math::Color const& color)
    {
        _ogreViewport->setBackgroundColour(Ogre::ColourValue(color.r, color.g, color.b, color.a));
    }
}}}
